Definizione delle views e template blade

Le viste rappresentano il componente di Laravel che si occupa di definire la struttura delle pagine HTML e dei dati che verranno servite agli utenti. Laravel supporta viste definite in semplici file PHP e viste Blade, un template system parecchio diffuso nel mondo della programmazione web. Il riconoscimento dell'engine è automatico e basato su una convenzione a livello di filename (se la vista ha estensione .php verrà utilizzato l'engine classico, altrimenti se la vista ha estensione .blade.php verrà utilizzato l'engine di blade).

Laravel favorisce l'utilizzo di blade in quanto strumento più avanzato sia funzionalmente che sintatticamente rispetto ai classici file PHP.

View e Controller

Le view vengono principalmente definite all'interno dei controller una volta impostata la logica di business dell'applicazione. Tutto avviene tramite l'helper view:

return view('nomeview', $datiDaPassareAllaView);

Le view vengono automaticamente cercate all'interno della folder resources/views. Sono disponibili anche subfolder all'interno del nome della view usando il carattere punto (.). L'estensione del file non viene mai comunicata esplicitamente delegando così a Laravel la scelta dell'engine.

Per esempio la view resources/views/user/detail.blade.php avrà come riferimento la stringa user.detail.

I parametri

I parametri alle view possono essere comunicati in due diversi modi, tramite il secondo parametro dell'helper view visto in precedenza o tramite il metodo with. Nel primo caso l'oggetto dovrebbe essere un array associativo, mentre nel secondo caso può essere anche un oggetto plain. Nel dettaglio queste due righe sono a tutti gli effetti equivalenti:

return view('user.detail', [ 'username' => 'abottarini', 'email' => 'ab@gmail.com']);
return view('user.detail')->with('username', 'abottarini')->with('email', 'ab@gmail.com');

I view composer

I view composer sono componenti avanzati che permettono di condividere dati tra view diverse evitando di duplicare le logiche di business per l'ottenimento dei dati. Devono essere definiti all'interno di un service provider (componente che introdurremo successivamente) e permettono di associare ad una determinata view un particolare metodo (o una closure).

In particolare con questo esempio comunichiamo al framework di invocare il metodo nomemetodo quando la view nomeview viene inclusa in altre view o invocata direttamente.

view()->composer('nomeview', 'nomemetodo');

Blade

Blade rappresenta il principale strumento per definire view all'interno di Lavarel. E' un linguaggio di templating che viene compilato in file PHP e viene cacheato in modo da non generare nessun tipo di overhead. I file Blade hanno l'estesione .blade.php ed è grazie a questa che Laravel li distingue da normali view PHP.

Ereditarietà

I template definiti con Blade sfruttano l'ereditarietà come in un normale linguaggio orientato agli oggetti. E' infatti possibile definire layout padri “astratti” e layout figli che li estendono e aggiungono funzionalità e sezioni HTML. I costrutti principali per utilizzare l'ereditarietà sono @yield e @section, guardiamo un esempio:

<!-- views/layouts/master.blade.php -->
<html>
    <head>
        <title>@yield('title')</title>
    </head>
    <body>
        <div class="sidebar">
	  	@yield('sidebar')
	  </div>

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>
<!-- views/view.blade.php -->
@extends('layouts.master')

@section('title', 'Page Title')

@section('sidebar')
    <p>This is my sidebar.</p>
@endsection

@section('content')
    <p>This is my content.</p>
@endsection

Il primo file rappresenta un layout, una sorta di scheletro astratto che presenta tre sezioni configurabili: title, sidebar e container definiti tramite il costrutto @yield. Il secondo file rappresenta invece una view concreta che estende il precedente layout e ne definisce le sezioni tramite appunto @section.

Non c'è limite al livello gerarchico che si può implementare. Possono esistere anche viste che estendono viste già complete con l'unico scopo di modificarne una sezione. Inoltre grazie al costrutto @parent è possibile embeddare in una vista figlia il contenuto del padre senza sovrascriverlo.

Stampa dei dati

Per visualizzare delle variabili all'interno dei template usiamo la sintassi {{ $nomevariabile }}. Uno strumento spesso sottovalutato è la possibilità di definire un default nel caso la variabile non sia definita: {{ $nomevariabile or 'stringa di default' }}. In automatico eventuali caratteri HTML vengono escapati da Laravel, ma nel caso fosse necessario stampare il valore della variabile senza filtri addizionali possiamo scrivere {!! $nomevariabile !!}.

Controllo del flusso

L'ereditarietà rappresenta la principale differenza di blade rispetto agli altri linguaggi di templating. Oltre a questo aspetto, Blade presenta comunque tutti gli altri strumenti classici. Grazie a @if, @elseif e @else possiamo definire template condizionali: Utilizzando @for, @foreach, @forelse, @empty e @while possiamo renderizzare strutture HTML ripetitive all'interno di cicli. Tramite @include sarà possibile includere frammenti comuni all'interno di view (spesso sfruttando i ViewComposer descritti in precedenza). Nel caso fosse necessario, sulla documentazione ufficiale sono presenti parecchi esempi per ciascun operatore.

Biblios parte 4: introduciamo le View

La quarta parte del nostro tutorial ci permetterà di avere finalmente qualcosa di funzionante. L'obiettivo sarà quello di definire due view per i nostri controller getHome e getBookDetail e creare dei finti dati da mostrare agli utenti.

Per iniziare possiamo modificare la nostra classe FrontendController aggiungendo due metodi privati che simulano l'interazione con il database e permettono di ottenere l'elenco dei libri disponibili (approfondire nel caso guardando i sorgenti) e modificando i metodi pubblici come segue:

public function getHome() {
		return view('home')->with('books', $this->getAllBooks());
	}

	public function getBookDetail($id) {
		return view('bookdetail')->with('book', $this->getBook($id));
	}
	

In questo modo abbiamo creato la logica di business per visualizzare nella home l'elenco di tutti i libri e le pagine di dettaglio. Passiamo ora alle views. Da best practice il primo passo è quello di definire un layout astratto per poi passare alla definizione delle varie pagine. Creiamo quindi il file resources/views/layout/biblios.blade.php:

<html>
	<head>
		<title>Biblios - @yield('title')</title>
	</head>
	<body>
		<h1>@yield('title')</h1>

		<div id="content">
			@yield('content')
		</div>
	</body>
</html>

e estendiamolo grazie a resources/views/home.blade.php

@extends('layouts.biblios')
@section('title', 'Home')
@section('content')
	@foreach($books as $index => $book)
		<h2>{{ $book->title }}</h2>
		<p>
			{{ $book->author }}<br/>
			<a href="{{ route('bookDetail', [ 'id' => $index ]) }}">Guarda dettaglio</a>
		</p>
	@endforeach
@endsection

Oltre alla home definiamo il template della pagina di dettaglio (approfondire nei sorgenti). Una volta realizzato possiamo finalmente lanciare l'applicazione (con php artisan serve) e iniziare a navigare tra le diverse pagine del portale.